import { useEffect, useRef, useState } from 'react';
import { Checkbox, Skeleton, App } from 'antd';

import { useDispatch } from 'react-redux';
import loadable from '@loadable/component';

import { customSetTimeout } from '@/utils';
import { queryQrCode, queryQrBindStatus } from '@/service/base';

import styles from './index.module.scss';

const QrCode = loadable(() => import('@/pages/components/QrCode'), {fallback: <Skeleton.Image active/>});

export default props => {
    const initState = () => ({
        url: '',
        status: 'loading', // active, expired, loading, scanned
        code: '', // uuid 查状态用

        agreement: true,
        errorMsg: '',
    });
    const [state, setState] = useState(initState);
    const dispatch = useDispatch();
    const { message } = App.useApp();
    const loopHandler = useRef(null);
    const { onOk } = props;


    // 请求二维码，成功后开启轮询，判断二维码是否被扫、是否过期
    const initQrImage = () => {
        setState(o => ({...o, status: 'loading'}));

        let postData = {};
        queryQrCode(postData).then(response => {
            if(OK_CODE === response?.code) {
                let data = response.data || {};
                setState(o => ({...o, status: 'active', url: data?.data || '', code: data?.code}));

                data?.code && loopQrImage(data?.code);
            }else{
                message.warning(response?.msg || response?.message || '失败');
                setState(o => ({...o, status: 'expired'}));
            }
        }).catch(e => {
            setState(o => ({...o, status: 'expired'}));
            message.error(e?.msg || e?.message || '失败');
        });
    };

    // 轮询二维码
    const loopQrImage = (code='') => {
        // 轮询是否扫码
        let count = 0;
        if(!code) {
            setState(o => ({...o, status: 'error', errorMsg: '缺少查询参数'}));
            return;
        }

        // 结束上一次的轮询
        loopHandler.current && loopHandler.current();
        // 开始本次轮询
        loopHandler.current = customSetTimeout(() => {
            if(count < 59) {
                count++;

                const formData = new FormData();
                formData.append('sceneStr', code);
                queryQrBindStatus(formData).then(response => {
                    if(OK_CODE === response?.code) {
                        const {token, user: userInfo, openId, inviterCode, expire} = response || {};

                        message.destroy();
                        loopHandler.current();
                        count = 1;

                        message.success('绑定成功！');

                        if(!userInfo?.openid) {
                            message.error(`获取TOKEN失败`);
                            setState(o => ({...o, status: 'error'}));
                            return;
                        }

                        // 设置token等信息后再跳转
                        localStorage.setItem('accessToken', token);
                        localStorage.removeItem('inviter_code');
                        // 关闭登录弹框, 更新用户信息
                        onOk(userInfo);
                    }else if(500 === response?.code) {
                    }else if(100 === response?.code) {
                        setState(o => ({...o, status: 'error', errorMsg: '该微信已绑定其他手机号，可联系客服处理'}));
                    }else{
                        setState(o => ({...o, status: 'error', errorMsg: response?.msg || '未知异常'}));
                    }
                }).catch(e => {
                    if(500 === e?.code) return;
                    if(100 === e?.code) {
                        setState(o => ({...o, status: 'error', errorMsg: '该微信已绑定其他手机号，可联系客服处理'}));
                        return;
                    }
                    setState(o => ({...o, status: 'error', errorMsg: e?.message || '未知异常'}));
                });
            }else{
                loopHandler.current && loopHandler.current();
                count = 1;

                setState(o => ({...o, status: 'expired'}));
            }
        }, 1500);
    };

    // 重新获取二维码
    const refresh = () => {
        message.destroy();
        if(state.agreement) {
            initQrImage();
        }else{
            message.warning(`请确认用户服务协议`);
        }
    };

    // 切换协议同意状态
    const onChangeAgree = e => {
        let {errorMsg, agreement} = state,
            checked = e.target.checked;

        if(agreement && !checked) { // 同意 -> 不同意
            errorMsg = '请确认用户服务协议';
        }else if(!agreement && checked) { // 不同意 -> 同意
            errorMsg = '';
        }
        // 如果不同意，那么就停止计时，弹出信息
        if(!checked) {
            loopHandler.current && loopHandler.current();
        }else{
            initQrImage();
        }

        setState(o => ({
            ...o,
            agreement: checked,
            errorMsg,
            status: checked ? 'loading' : 'error',
        }));
    };

    const customStatusRender = info => {
        const { errorMsg } = state;
        var _a, _b, _c;
        switch (info.status) {
            case 'error':
                return (
                    <div style={{color: 'var(--error)'}}>{errorMsg || '发生异常，稍后重试'}</div>
                );
            default:
                return null;
        }
    };

    // 组件加载时请求二维码地址
    useEffect(() => {
        initQrImage();

        return () => {
            loopHandler.current && loopHandler.current();
        };
    }, []);

    return (
        <>
            <div className={styles['container']}>
                <div className={styles['qrcode']}>
                    <QrCode
                        url={state.url}
                        status={state.status}
                        onRefresh={refresh}
                    />
                </div>
            </div>
        </>
    )
};